iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0

上篇介紹到了巢狀的if結構,可是如果有太多的if,會讓程式的複雜度提高、閱讀不易、維護難度也提高。這時候可以考慮使用switch敘述。

switch的架構

switch 寫法如下:

using System;

public class Example
{
   public static void Main()
   {
      int caseSwitch = 1;
      
      switch (caseSwitch)//switch (比對的運算式)
      {
          case 1://狀況一走這個
              Console.WriteLine("Case 1");
              break;
          case 2:
          case 3://狀況二、三走這個
              Console.WriteLine("Case 2或3");
              break;
          default://以上都不符合走這個
              Console.WriteLine("Default case");
              break;
      }
   }
}

switch 陳述式包含一個或多個參數區段。每個參數區段都包含一或多個「case 標籤」 (case或預設標籤),後面接著一或多個陳述式。

它的運行規則規則是,判斷比對的運算式的值,符合哪一種狀況(case),就執行該case下方的動作。
以上面的程式碼來看,用caseSwitch當作判斷式,當它是1的時候,輸出Case 1,當它是2或3的時候,輸出Case 2或3。

default表示,當值不符合任何一個case時,會直接跳到default的部分,運行下方的程式碼。

switch的撰寫規則

  1. default case可以依照任何順序放在switch裡,會先比對完所有case才會跳到default

  2. default case可以不存在,若比對不到任何case,也沒有default case,則程式會離開switch{ }

  3. 不同case可以對應到同一個陳述式(程式區段),如上方的case2跟case3,都是執行Console.WriteLine("Case 2或3");

  4. 同一case不能對應到不同陳述式(程式區段),以下為錯誤示範

int caseSwitch = 1;
      
      switch (caseSwitch)//switch (比對的運算式)
      {
          case 1:
              Console.WriteLine("Case 1");
              break;
          case 2:
          case 2://有兩個case2這樣是不行的
              Console.WriteLine("Case 2或3");
              break;
          default:
              Console.WriteLine("Default case");
              break;
      }
  1. switch陳述式中只會執行一個參數區段(一個case)。C#不允許從某個參數區段繼續執行至另一個參數區段。所以所有的參數區段都要使用 break、goto、throw或 return 陳述式明確地結束。

補充break、goto、throw、return

  • break:會跳出其所在的最接近封閉式迴圈(最接近的{ })或switch陳述式。
  • goto:將程式控制權轉移到特定的標籤或switch的case,也可以用來跳出深度巢狀的迴圈。
  • throw:終止執行在其中出現的方法,並且將控制權傳回給呼叫方法。
  • return:跳出最接近的函式,例如整個switch寫在main()這個方法裡,return是跳出main()而不只是跳出switch。
    • 以下為錯誤示範

       int caseSwitch = 1;
      
              switch (caseSwitch)//switch (比對的運算式)
              {
                  case 1:
                      Console.WriteLine("Case 1");
                      //break;
                  case 2://把break去掉後,case1跑完會想繼續往下走,但是不能從一個case直接移到另一個case,所以會報錯
                  case 3:
                      Console.WriteLine("Case 2或3");
                      break;
                  default:
                      Console.WriteLine("Default case");
                      break;
              }
      
      • 以下這種例外編譯可以過,但是會無窮迴圈XD
        case3沒有加break、goto、throw或 return ,但是他成功阻止了case3往下走到default區,所以編譯可以過
       int caseSwitch = 3;
      
              switch (caseSwitch)//switch (比對的運算式)
              {
                  case 1:
                      Console.WriteLine("Case 1");
                      break;
                  case 2:
                      Console.WriteLine("Case 2");
                      break;
                  case 3:
                  while (true)//while是無窮迴圈,滿足條件就會一直執行,後續文章會介紹到
                          Console.WriteLine("夭壽進入無窮迴圈惹");
                      //break;沒有break
                  default:
                      Console.WriteLine("Default case");
                      break;
              }
      

      輸出結果就會一直輸出"夭壽進入無窮迴圈惹"
      https://ithelp.ithome.com.tw/upload/images/20190912/20120055iJz6dcEXyt.png

  1. 在C#6中,比對的運算式必須是傳回下列類型之值的運算式︰bool、整數、char、string、enum值、const變數名稱。不允許重複常數值,標籤彼此互斥。由於只會有一個,所以case順序不重要。

  2. C#7開始,比對的運算式可以是任何非 Null 運算式,不需互斥。由於可以接受不同模式的比對運算式,而且只會執行符合case的第一個參數區段中的陳述式,所以順序變得很重要,請看下方例子。

這會報錯,因為hi是string a這個case,也是hi這個case
https://ithelp.ithome.com.tw/upload/images/20190912/20120055AaoKXl9u6z.png

這樣有兩個解法:

  • 把string a跟hi的case互換,順序真的很重要
  string caseSwitch = "Hi";

            switch (caseSwitch) //switch (比對的運算式)
            {
                case "Hi":
                    Console.WriteLine("Case 2");//hi也會符合這一個條件
                    break;
                case string a:
                    Console.WriteLine("Case a");//hi符合這一個條件
                    break;
                
               
                default:
                    Console.WriteLine("Default case");
                    break;

            }
  • 利用when排除特例
string caseSwitch = "Hi";

            switch (caseSwitch) //switch (比對的運算式)
            {
                case string a when a!="Hi":
                    Console.WriteLine("Case a");//hi被排除了
                    break;
                case "Hi":
                    Console.WriteLine("Case 2");//hi也會符合這一個條件
                    break;
               
                default:
                    Console.WriteLine("Default case");
                    break;

            }

switch例子

在我們曾經(好啦我是曾經QQ)的漫長學生生涯裡,一定常常遇到選擇題的作答。以下就用一題選擇題來看看switch可以怎麼運用(ゝ∀・)b

題目:請問以下哪些話符合今天中秋節?
(1)應該要划龍舟(2)要穿紅通通小心年獸(3)去找聖誕老公公堆雪人(4)鐵人賽還是要發文QQ

程式碼:

 Console.WriteLine("請問以下哪些話符合今天中秋節?");
            Console.WriteLine("A.應該要划龍舟 B.要穿紅通通小心年獸 C.去找聖誕老公公堆雪人 D.鐵人賽還是要發文QQ");
            string answer = Console.ReadLine();
            switch (answer) 
            {
                case "A"://讀進來的A是字串型態喔
                case "B":
                case "C":
                    Console.WriteLine("給你十秒google一下什麼是中秋節");
                    break;
                case "D":
                    Console.WriteLine("沒錯這就是2019的中秋節QQ");
                    break;

                default:
                    Console.WriteLine("欸認真回答啦");
                    break;

            }

            Console.ReadKey();

大家中秋節快樂~~

https://ithelp.ithome.com.tw/upload/images/20190913/201200554GXlEpAIh2.png

參考資料

switch(C#參考)
阿沙布魯-朝風呂:C#關鍵字-switch的使用


上一篇
Day11-C#的條件判斷- if else(例子:比大小、賣場折扣、判斷腰圍肥胖)
下一篇
Day13-C#的無條件進入、無條件捨去、跟你想的不一樣的四捨五入!(補充:怎麼對小數點後某位數作無條件捨去或是無條件進入?)
系列文
C#與ASP.Net入門-我要成為工程師!!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tim80411
iT邦新手 5 級 ‧ 2020-09-19 13:13:12

你好,我看了好幾遍,但還是為什麼case string a 和 case "Hi" 調換位置就可以run,我無法理解的是:就算調換位置但還是同時符合兩個case應該會報錯阿~~~~~~

希望可以獲得解答QQ

1.我們可以先這麼想,string a包含了"Hi",但反之不成立,string的範圍比較大
2.C#7起的世界case間不一定要互斥,所以順序的影響性才會提升。CS8120的錯誤發生在,它判定已經符合前面的case(string a),跑進去之後break,永遠都不會跑到case "Hi",所以報錯。順序互換後,我丟一個參數進來,它有機會不是"Hi"然後跑到下一個case string a,所以不會報錯~

希望有解答你的疑惑~

我要留言

立即登入留言